#ifndef PROTO_H_
#define PROTO_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <arpa/inet.h>
#include <assert.h>

enum PKG_CMD
{
	ID_C2S_REQ_CALC = 0,
	ID_S2C_RES_CALC,
};

enum CALC_OP
{
	E_CALC_ADD = 0,
	E_CALC_SUB,
	E_CALC_MUL,
	E_CALC_DIV,
};

typedef struct C2S_PKG
{
	int16_t cmd;
	int16_t calc_op;
	int32_t arg_1;
	int32_t arg_2;
	int32_t arg_3;
	char  buffer[128];
}C2S_PKG;

static __attribute__((unused))  int serialize_pkg(void* pkg_ptr, char* buffer, size_t* buffer_len)
{
	assert(pkg_ptr && buffer && buffer_len);
	if(*buffer_len < sizeof(struct C2S_PKG))
		return -1;
	*buffer_len = sizeof(struct C2S_PKG);

	struct C2S_PKG* pkg = (struct C2S_PKG*)pkg_ptr;
	*(int16_t*)buffer = htons(pkg->cmd);
	*(int16_t*)(buffer + 2) = htons(pkg->calc_op);
	*(int32_t*)(buffer + 4) = htonl(pkg->arg_1);
	*(int32_t*)(buffer + 8) = htonl(pkg->arg_2);
	*(int32_t*)(buffer + 12) = htonl(pkg->arg_3);
	memcpy(buffer + 16, pkg->buffer, sizeof(pkg->buffer));
	return 0;
};

static __attribute__((unused))  int deserialize_pkg(void* pkg_ptr, char* buffer, size_t buffer_len)
{
	assert(pkg_ptr && buffer);
	if(buffer_len != sizeof(struct C2S_PKG))
		return -1;

	struct C2S_PKG* pkg = (struct C2S_PKG*)pkg_ptr;
	pkg->cmd = ntohs(*(int16_t*)buffer);
	pkg->calc_op = ntohs(*(int16_t*)(buffer + 2));
	pkg->arg_1 = ntohl(*(int32_t*)(buffer + 4));
	pkg->arg_2 = ntohl(*(int32_t*)(buffer + 8));
	pkg->arg_3 = ntohl(*(int32_t*)(buffer + 12));
	memcpy(pkg->buffer, buffer + 16, sizeof(pkg->buffer));
	return 0;
};

#ifdef __cplusplus
}
#endif

#endif // PROTO_H_




